# -*- coding: utf-8 -*-
import pygame
from Setting import *

class Snake(object):

    def __init__(self, game):
        self.game = game
        self.init()
        self.action_name = 'snake move'
        self.game.add_update_action(self.action_name, self.move, 1000 / self.speed)
        self.sound_eat = pygame.mixer.Sound(EAT_SOUND)
        self.sound_hit = pygame.mixer.Sound(HIT_SOUND)
        self.sound_eat.set_volume(0.1)
        self.sound_hit.set_volume(0.1)

    def init(self):
        self.head = INIT_POS
        self.length = INIT_LENGTH
        self.direction = INIT_DIRECTION
        self.new_direction = INIT_DIRECTION
        self.speed = INIT_SPEED
        self.body = [(x, self.head[1]) for x in range(self.head[0], self.head[0] - self.length, -1)]
        self.score = 0
        self.alive = True
        self.head_color = ALIVE_HEAD_COLOR
        self.body_color = ALIVE_BODY_COLOR

    def move(self):
        if not self.alive:
            return
        # 更新方向
        self.direction = self.new_direction

        # 预判下个位置
        next = (self.body[0][0] + self.direction[0], self.body[0][1] + self.direction[1])

        # 判断是否死亡
        if (not (0 <= next[0] < COL and 0 <= next[1] < ROW)) or next in self.body[:-1]:
            self.die()
            return

        # 更新数据
        self.body.insert(0, next)
        if next == self.game.food.pos:
            self.eat()
        else:
            self.body.pop()

    def eat(self):
        self.sound_eat.play()
        self.length += 1
        self.score += 10
        self.speed = min(5, self.score / 20 + INIT_SPEED)
        self.game.add_update_action(self.action_name, self.move, 1000 / self.speed)
        self.game.food.set_pos()

    def die(self):
        self.sound_hit.play()
        self.head_color = DEAD_HEAD_COLOR
        self.body_color = DEAD_BODY_COLOR
        self.alive = False

    def respawn(self):
        if self.alive:
            return
        self.init()
        self.game.food.set_pos()

    def turn(self, direction):
        if self.direction[0] * direction[0] + self.direction[1] * direction[1] == 0:
            self.new_direction = direction

    def draw(self):
        for i, e in enumerate(self.body):
            if i - 1 >= 0:
                dx = self.body[i - 1][0] - self.body[i][0]
                dy = self.body[i - 1][1] - self.body[i][1]
                start_pos = (e[0] * CELL + CELL / 2, e[1] * CELL + CELL / 2)
                end_pos = (e[0] * CELL + dx * CELL / 2 + CELL / 2, e[1] * CELL + dy * CELL / 2 + CELL / 2)
                width = (CELL / 4) if (i != self.length - 1) else (CELL / 6)
                color = self.body_color
                pygame.draw.line(self.game.game_zone, color, start_pos, end_pos, width)
            if i + 1 < self.length:
                dx = self.body[i][0] - self.body[i + 1][0]
                dy = self.body[i][1] - self.body[i + 1][1]
                start_pos = (e[0] * CELL - dx * CELL / 2 + CELL / 2, e[1] * CELL - dy * CELL / 2 + CELL / 2)
                end_pos = (e[0] * CELL + CELL / 2, e[1] * CELL + CELL / 2)
                width = (CELL / 4) if (i != 0) else (CELL / 3)
                color = self.body_color
                pygame.draw.line(self.game.game_zone, color, start_pos, end_pos, width)
            if i == 0:
                pos = (e[0] * CELL + CELL / 2, e[1] * CELL + CELL / 2)
                color = self.head_color
                pygame.draw.circle(self.game.game_zone, color, pos, CELL / 3)
